#ifndef FILEPATH_H
#define FILEPATH_H

#include "FileOperation.h"

namespace Pan
{

    /**
     * @brief 该类包含了一些用于路径操作的函数
     * @author 盼鸽鸽
     */
    class FilePath
    {

    public:
        /**
         * @brief 获取当前EXE文件的绝对路径
         * @return 路径对象
         */
        static FilePath this_exe_file_path();

    public:
        /**
         * @brief 获取程序的工作目录
         * @return 路径对象
         */
        static FilePath working_directory();

    public:
        /**
         * @brief 路径对象保存绝对路径的缓冲区的默认大小
         */
        static const unsigned int default_buffer_size = 512;

    public:
        /**
         * @brief 从路径中移除文件名扩展名
         * @param path 路径（相对路径或绝对路径）
         * @param len 字符串的长度，默认值0表示让函数自动计算长度。
         * @return 操作成功返回字符串的长度，操作失败返回0。
         */
        static unsigned int remove_extension(wchar_t *const path, unsigned int len = 0);

        /**
         * @brief 移除路径最后面的那个反斜杠（如果有的话）
         * @param path 路径字符串
         * @param len 字符串的长度，默认是0，表示要函数中计算字符串的长度
         * @return 字符串的长度
         */
        static unsigned int remove_tail_backslash(wchar_t *path, unsigned int len = 0);

        /**
         * @brief 在路径字符串的末尾添加反斜杠（如果没有的话）
         * @param path 路径字符串
         * @param len 字符串的长度，默认是0，表示要函数中计算字符串的长度
         * @return 字符串的长度
         */
        static unsigned int add_tail_backslash(wchar_t *path, unsigned int len = 0);

        /**
         * @brief 从一个路径中查找文件名的位置
         * @param path 指向路径的指针
         * @param len 路径字符串的长度
         * @return 指针（找不到时返回空指针或者指向空字符串的指针）
         */
        static const wchar_t *find_file_name(const wchar_t *path, unsigned int len = 0);

        static const wchar_t *find_extension(const wchar_t *path, unsigned int len = 0);

    public:
        /**
         * @brief 构造一个文件路径对象
         * @param path 路径
         */
        FilePath(const wchar_t *path);

    public:
        /**
         * @brief ~FilePath()
         */
        ~FilePath();

    public:
        /**
         * @brief 判断指针是否为空，为空表示内存分配失败，对象不可用
         * @return bool值
         */
        inline bool is_nullptr() const { return this->fp == nullptr; }

    public:
        /**
         * @brief 判断是否为空字符串
         * @return bool值
         */
        inline bool is_empty() const { return this->fp[0] == L'\0'; }

    public:
        /**
         * @brief 清空路径
         */
        inline void clear() const { this->fp[0] = L'\0'; }

    public:
        /**
         * @brief 获取绝对路径
         * @return 指针
         */
        inline const wchar_t *full_path() const { return this->fp; }

    public:
        /**
         * @brief 获取缓冲区的指针
         * @return 指针
         */
        inline wchar_t *pointer() const { return this->fp; }

    public:
        /**
         * @brief 移除路径最后的反斜杠（如果有的话）
         * @return 路径字符串的长度
         */
        inline unsigned int remove_tail_backslash() const
        {
            return this->remove_tail_backslash(this->fp);
        }

    public:
        /**
         * @brief 在路径最后添加反斜杠（如果没有的话）
         * @return 路径字符串的长度
         */
        inline unsigned int add_tail_backslash() const { return this->add_tail_backslash(this->fp); }

    public:
        /**
         * @brief 获取文件名
         * @return 指针，找不到返回空指针或空字符串
         */
        const wchar_t *file_name() const { return FilePath::find_file_name(this->fp); }

    public:
        /**
         * @brief 获取文件扩展名
         * @return 指针，找不到返回空指针或空字符串
         */
        const wchar_t *extension() const { return FilePath::find_extension(this->fp); }

    public:
        /**
         * @brief 在路径后追加一个节点
         * @param name 节点名称
         * @return 字符串的长度
         */
        unsigned int append_node(const wchar_t *name) const;

    public:
        /**
         * @brief 转换为父路径
         * @return 是否转换成功
         */
        bool to_parent_path() const;

    public:
        inline bool is_existing_path() const
        {
            return FileOperation::is_existing_path(this->fp);
        }

    public:
        inline bool is_existing_file() const
        {
            return FileOperation::is_existing_file(this->fp);
        }

    public:
        inline bool is_existing_directory() const
        {
            return FileOperation::is_existing_directory(this->fp);
        }

    protected:
        /**
         * @brief 指向一个绝对路径的开头
         */
        wchar_t *fp;
    };

} // namespace Pan

#endif // FILEPATH_H
